home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 4
/
Meeting Pearls Vol. IV (1996)(GTI - Schatztruhe)[!].iso
/
Pearls
/
dev
/
Oberon
/
OberonV4
/
system
/
Compiler.Mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1995-05-26
|
6KB
|
187 lines
Syntax10.Scn.Fnt
StampElems
Alloc
26 May 95
MODULE Compiler;
(* Compiler for Oberon-2 on Sun-3 workstations.
Diplomarbeit Samuel Urech
Programming language: Oberon-2 on Ceres-1.
Date: 3.11.92 Current version:
IMPORT
Texts, TextFrames, Viewers, Oberon,
OPP, OPB, OPV, OPT, OPS, OPC, OPL, OPM;
CONST
OptionChar = "\";
ShowCommand = "OPdump.Show";
SignOnMessage = "Compiler SU 26.5.95";
(* compiler options: *)
inxchk = 0; (* index check on *)
ovflchk = 1; (* overflow check on *)
ranchk = 2; (* range check on *)
typchk = 3; (* type check on *)
newsf = 4; (* generation of new symbol file allowed *)
ptrinit = 5; (* pointer initialization *)
intprinf = 6; (* inter-procedural information about register allocation used *)
assert = 7; (* assert evaluation *)
findpc = 8; (* find text position of breakpc *)
nilchk = 9; (* NIL check *)
defopt = {inxchk, typchk, ptrinit, assert, nilchk}; (* default options *)
prog*: OPT.Node;
showTree, watch: BOOLEAN;
(* global because of the GC call on Ceres*)
source: Texts.Text;
sourceR: Texts.Reader;
S: Texts.Scanner;
v: Viewers.Viewer;
W: Texts.Writer;
PROCEDURE Module*(source: Texts.Reader; options: ARRAY OF CHAR; breakpc: LONGINT; log: Texts.Text; VAR error: BOOLEAN);
VAR key: LONGINT; opt: SET; ch: CHAR; newSF: BOOLEAN;
p: OPT.Node; modName: OPS.Name;
res, i: INTEGER;
command: ARRAY 32 OF CHAR;
BEGIN
IF watch THEN command := "System.Watch"; Oberon.Call(command, Oberon.Par, FALSE, res) END ;
opt := defopt; i := 0;
REPEAT
ch := options[i]; INC(i);
IF ch = "x" THEN opt := opt / {inxchk}
ELSIF ch = "v" THEN opt := opt / {ovflchk}
ELSIF ch = "r" THEN opt := opt / {ranchk}
ELSIF ch = "t" THEN opt := opt / {typchk}
ELSIF ch = "s" THEN opt := opt / {newsf}
ELSIF ch = "p" THEN opt := opt / {ptrinit}
ELSIF ch = "i" THEN opt := opt / {intprinf}
ELSIF ch = "a" THEN opt := opt / {assert}
ELSIF ch = "f" THEN opt := opt / {findpc}
ELSIF ch = "n" THEN opt := opt / {nilchk}
END
UNTIL ch = 0X;
OPM.Init(source, log); OPS.Init; OPT.Init; OPB.typSize := OPV.TypSize;
newSF := newsf IN opt;
OPT.OpenScope(0, NIL);
OPP.Module(p, modName);
IF OPM.noerr THEN
OPL.Init(opt);
OPV.Init(opt, breakpc);
OPV.AdrAndSize;
OPM.errpos := 0;
key := OPM.NewKey();
OPT.Export(modName, newSF, key);
IF newSF THEN OPM.LogWStr(" new symbol file") END ;
IF showTree THEN prog := p; command := ShowCommand;
Oberon.Call(command, Oberon.Par, FALSE, res); prog := NIL
END ;
IF OPM.noerr THEN
OPM.OpenRefObj(modName);
OPC.Init(opt);
OPV.Module(p);
IF OPM.noerr THEN
OPL.OutCode(modName, key);
IF OPM.noerr THEN
OPM.CloseRefObj;
OPM.LogWNum(OPL.pc, 8);
OPM.LogWNum(OPL.dsize, 8);
END;
END;
END;
OPL.Close;
END ;
OPT.CloseScope; OPT.Close;
OPM.LogWLn; error := ~OPM.noerr;
IF watch THEN command := "System.Watch"; Oberon.Call(command, Oberon.Par, FALSE, res) END
END Module;
PROCEDURE Compile*;
VAR beg, end, time, pos: LONGINT; error: BOOLEAN; ch: CHAR;
PROCEDURE Do(filename: ARRAY OF CHAR; beg: LONGINT);
VAR S1: Texts.Scanner; line, i: INTEGER; options: ARRAY 32 OF CHAR;
fbeg, fend, ftime, breakpc: LONGINT; ftext: Texts.Text; f: BOOLEAN;
BEGIN
Texts.WriteString(W, filename); Texts.WriteString(W, " compiling ");
Texts.OpenScanner(S1, source, beg); Texts.Scan(S1);
IF (S1.class = Texts.Name) & (S1.s = "MODULE") THEN
Texts.Scan(S1);
IF S1.class = Texts.Name THEN Texts.WriteString(W, S1.s) END
END ;
Texts.Append(Oberon.Log, W.buf);
line := S.line; pos := Texts.Pos(S); i := 0; f := FALSE;
Texts.Scan(S);
IF (S.line = line) & (S.class = Texts.Char) & (S.c = OptionChar) THEN
ch := S.nextCh;
WHILE ((ch >= "0") & (ch <= "9") OR (ch >= "a") & (ch <= "z")) & (i < LEN(options) - 1) DO
options[i] := ch; INC(i);
IF ch = "f" THEN f := ~f END ;
Texts.Read(S, ch)
END ;
S.nextCh := ch;
pos := Texts.Pos(S); Texts.Scan(S)
END ;
options[i] := 0X;
IF f THEN
LOOP
Oberon.GetSelection(ftext, fbeg, fend, ftime);
IF ftime >= 0 THEN
Texts.OpenScanner(S1, ftext, fbeg); Texts.Scan(S1);
IF S1.class = Texts.Int THEN breakpc := S1.i; EXIT END
END ;
Texts.WriteString(W, " pc not selected"); Texts.WriteLn(W);
Texts.Append(Oberon.Log, W.buf); error := TRUE; RETURN
END
END ;
Texts.OpenReader(sourceR, source, beg);
Module(sourceR, options, breakpc, Oberon.Log, error)
END Do;
BEGIN
error := FALSE;
Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
IF S.class = Texts.Char THEN
IF S.c = "*" THEN
v := Oberon.MarkedViewer();
IF (v.dsc # NIL) & (v.dsc.next IS TextFrames.Frame) THEN
source := v.dsc.next(TextFrames.Frame).text; Do("", 0)
END
ELSIF S.c = "^" THEN
Oberon.GetSelection(source, beg, end, time);
IF time >= 0 THEN
Texts.OpenScanner(S, source, beg); pos := Texts.Pos(S); Texts.Scan(S); NEW(source);
WHILE (S.class = Texts.Name) & (pos < end) & ~error DO
Texts.Open(source, S.s);
IF source.len # 0 THEN Do(S.s, 0)
ELSE
Texts.WriteString(W, S.s); Texts.WriteString(W, " not found");
Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); error := TRUE
END
END
END
ELSIF S.c = "@" THEN
Oberon.GetSelection(source, beg, end, time);
IF time >= 0 THEN Do("", beg) END
END
ELSE NEW(source);
WHILE (S.class = Texts.Name) & ~error DO
Texts.Open(source, S.s);
IF source.len # 0 THEN Do(S.s, 0)
ELSE
Texts.WriteString(W, S.s); Texts.WriteString(W, " not found");
Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); error := TRUE
END
END
END ;
Oberon.Collect(0)
END Compile;
PROCEDURE ShowTree*;
BEGIN showTree := TRUE
END ShowTree;
PROCEDURE HideTree*;
BEGIN showTree := FALSE
END HideTree;
PROCEDURE DoWatch*;
BEGIN watch := TRUE
END DoWatch;
PROCEDURE DontWatch*;
BEGIN watch := FALSE
END DontWatch;
BEGIN
(* HideTree; DontWatch; *) prog := NIL; Texts.OpenWriter(W);
Texts.WriteString(W, SignOnMessage); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
END Compiler.